不管Proc還是lambda他們都是Proc
> Proc.new {} .inspect
=> "#<Proc:0x00007f8e099ff328@(irb):1>"
> -> {} .inspect
=> "#<Proc:0x00007f8e099fc2e0@(irb):2 (lambda)>"
Proc是程序物件,可以將Ruby的程式碼保存起來,並且在需要的時候再執行它,或當做block傳入其他函數。
cat = Proc.new {|x| do something... }
也可以寫成
cat = Proc.new do |x|
do something...
end
cat = Proc.new { |n| n + 2 }
p cat.call(1)
p cat[1]
p cat.(1)
p cat.===(1)
block也可以轉成lambda,與proc有物件有些微不同,lambda表現更像是常見的匿名函數。
dog = lambda {|x| do something... }
或 ->{ }
這種寫法就是lambda
dog = -> (x) { do something... }
呼叫lambda的方法
dog = Proc.new { |n| n + 2 }
p dog.call(1)
p dog[1]
p dog.(1)
p dog.===(1)
大家都會說他們兩個很像,但有什麼差異呢?我們從引數跟回傳來看
Proc對引數給的數量比較沒有特別要求,不管給多給少都會給過。
> Proc.new {|arg1, arg2| puts "args: #{arg1}, #{arg2}"}.call(1)
#=> args: 1
> Proc.new do |arg1, arg2|
puts "args: #{arg1}, #{arg2}"
end.call(1,2,3)
#=> args: 1, 2
lambda對給的引數數量較為嚴格。如果不尊守規定,會出現ArgumentError錯誤。
> ->(arg1, arg2) {}.call(1)
#=> wrong number of arguments (given 1, expected 2) ArgumentError
> ->(arg1, arg2) {}.call(1,2,3)
#=> wrong number of arguments (given 3, expected 2) ArgumentError
Proc使用return之後,就不會再返回
def proc_return
puts "Before"
Proc.new {return}.call
puts "After"
end
proc_return
# Before
在lambda返回之後
lambda使用return之後,會再返回執行
def lambda_return
puts "Before"
lambda {return}.call
puts "After"
end
lambda_return
# Before
# After
參考連結:
Proc vs Lambda in Ruby
Ruby - block概念與相關寫法